import java.io.PrintStream;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: AliceMana
 * Date: 2022-09-21
 * Time: 8:04
 */
public class MySingleList {
    static class ListNode {
        int val;
        MySingleList.ListNode next;

        ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;

    //头插法
    public void addFirst(int data){
        ListNode node = new ListNode(data);
        node.next = head;
        head = node;
    }

    //尾插法
    public void addLast(int data){
        ListNode node = new ListNode(data);
        ListNode cur = this.head;
        if(cur == null) {
            this.head = node;
        }else {
            while (cur.next != null) {
                cur = cur.next;
            }
            //cur已经是尾巴节点了
            cur.next = node;
        }
    }

    //遍历链表
    public void display() {
        ListNode cur = this.head;
        while (cur != null) {
            System.out.print(cur.val+" ");
            cur = cur.next;
        }
        System.out.println();
    }

    //逆置单链表
    public ListNode reverseList() {
        //讨论的是 没有节点
        if(head == null) {
            return null;
        }
        //讨论的是 只有一个节点
        if(head.next == null) {
            return head;
        }
        ListNode cur = head.next;
        head.next = null;
        while (cur != null) {
            ListNode curNext = cur.next;
            cur.next = head;
            head = cur;
            cur = curNext;
        }
        return head;
    }

    //求单链表的长度
    public int size(){
        int count = 0;
        ListNode cur = this.head;
        while (cur != null) {
            count++;
            cur = cur.next;
        }
        return count;
    }

    //任意位置插入,第一个数据节点为0号下标
    public void addIndex(int index, int data){
        if(index < 0 || index > size()) {
            System.out.println("index位置不合法！");
            throw new IndexWrongFulException("index位置不合法");
        }
        if(index == 0) {
            addFirst(data);
            return;
        }
        if(index == size()) {
            addLast(data);
            return;
        }
        //1、先走index-1步，找到cur
        ListNode cur = findIndexSubOne(index);
        ListNode node = new ListNode(data);
        //2、修改指向
        node.next = cur.next;
        cur.next = node;
    }

    //找到当前位置的前驱
    private ListNode findIndexSubOne(int index) {
        ListNode cur = this.head;
        while (index-1 != 0) {
            cur = cur.next;
            index--;
        }
        return cur;
    }

    //删除单链表第i个元素
    public void listDelete(int index) {
        if(index < 0 || index > size()) {
            System.out.println("index位置不合法！");
            throw new IndexWrongFulException("index位置不合法");
        }
        //1、先走index-1步，找到cur
        ListNode cur = findIndexSubOne(index);
        cur.next = cur.next.next;
    }

    //查找单链表中第i个元素
    public int getElem(int index) {
        if(index < 0 || index > size()) {
            System.out.println("index位置不合法！");
            throw new IndexWrongFulException("index位置不合法");
        }
        //1、先走index-1步，找到cur
        ListNode cur = findIndexSubOne(index);

        return cur.next.val;
    }

    //查找是否包含关键字key是否在单链表当中
    public boolean contains(int key){
        ListNode cur = this.head;
        while (cur != null) {
            if(cur.val == key) {
                return true;
            }
            cur = cur.next;
        }
        return false;
    }

    //清空
    public void clear() {
        this.head = null;
    }
}


class Test{
    public static void menu() {
        System.out.println("1.头插法");
        System.out.println("2.尾插法");
        System.out.println("3.遍历");
        System.out.println("4.逆置");
        System.out.println("5.求长度");
        System.out.println("6.i位置插入元素");
        System.out.println("7.删除第i个元素");
        System.out.println("8.查找第i个元素");
        System.out.println("9.查找链表是否包含key");
        System.out.println("10.清空单链表");
        System.out.println("(注意:所有元素的坐标从0开始)");
    }
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        MySingleList mySingleList = new MySingleList();
        while (true) {
            menu();
            System.out.println("请输入你要进行的操作:");
            int input = in.nextInt();
            int data;
            switch (input) {
                case 1:
                    PrintStream old=System.out;
                    //System.setOut(new PrintStream(""));

                    System.out.println("请输入你要插入的值:");
                    data = in.nextInt();
                    mySingleList.addFirst(data);

                    //System.setOut(old);
                    break;

                case 2:
                    System.out.println("请输入你要插入的值:");
                    data = in.nextInt();
                    mySingleList.addLast(data);
                    break;
                case 3:
                    System.out.println("===============");
                    mySingleList.display();
                    System.out.println("===============");
                    break;
                case 4:
                    mySingleList.reverseList();
                    break;
                case 5:
                    System.out.println("长度为:"+mySingleList.size());
                    break;
                case 6:
                    System.out.println("请输入要插入的位置:");
                    int index = in.nextInt();
                    System.out.println("请输入要插入的元素:");
                    data = in.nextInt();
                    mySingleList.addIndex(index, data);
                    break;
                case 7:
                    System.out.println("请输入要删除的位置:");
                    index = in.nextInt();
                    mySingleList.listDelete(index);
                    break;
                case 8:
                    System.out.println("请输入要查找的位置:");
                    index = in.nextInt();
                    System.out.println("第"+index+"个元素为:"+mySingleList.getElem(index));
                    break;
                case 9:
                    System.out.println("请输入要查找的元素:");
                    data = in.nextInt();
                    System.out.println(mySingleList.contains(data));
                    break;
                case 10:
                    mySingleList.clear();
                    break;
                default:
                    System.out.println("输入错误请重新输入");
                    break;
            }
        }
    }
}
